package com.yaozheng.vocationaltraining.service.impl;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.RandomAccessFile;

import net.sf.json.JSONObject;

import org.androidannotations.annotations.Background;
import org.androidannotations.annotations.EBean;

import com.squareup.okhttp.Callback;
import com.squareup.okhttp.Request;
import com.squareup.okhttp.Response;
import com.squareup.okhttp.ResponseBody;
import com.yaozheng.vocationaltraining.iview.IVideoCoursewareOperatingView;
import com.yaozheng.vocationaltraining.iview.IVideoCoursewareView;
import com.yaozheng.vocationaltraining.service.BaseDownloadStatusListenerService;
import com.yaozheng.vocationaltraining.utils.ErrorUtils;
import com.yaozheng.vocationaltraining.utils.TypeUtils;
import com.yaozheng.vocationaltraining.utils.http.okhttp.OkHttpClientManager;

/**
 * 视频课件下载管理
 * 
 * @author Administrator
 * 
 */
@EBean
public class VideoCoursewareDownloadServiceImpl extends
		BaseDownloadStatusListenerService implements Callback {
	/**
	 * 视频文件后缀名
	 */
	public static final String VIDEO_COURSEWARE_EXTENSION = ".mp4";

	/**
	 * 下载中后缀名
	 */
	public static final String VIDEO_COURSEWARE_DOWNLOAD_EXTENSION = ".download";

	/**
	 * 文件流缓冲大小
	 */
	public static final int FILE_STREAM_BUFFER_SIZE = 1024;

	IVideoCoursewareOperatingView iVideoCoursewareView;
	/**
	 * 本地视频文件
	 */
	File localVideoCacheFile;
	/**
	 * 本地下载文件
	 */
	File localVideoDownloadFile;

	String error;

	RandomAccessFile outRandom = null;
	long fileLength;

	public void init(IVideoCoursewareOperatingView iVideoCoursewareView) {
		this.iVideoCoursewareView = iVideoCoursewareView;
	}

	@Background
	@Override
	public void download(JSONObject jsonObject) {
		try {
			error = null;
			String id = TypeUtils.getJsonString(jsonObject, "id");
			File cacheDir = new File(
					iVideoCoursewareView.getLocalVideoCacheDir());
			if (!cacheDir.exists()) {
				cacheDir.mkdirs();
			}
			localVideoCacheFile = new File(cacheDir, id
					+ VIDEO_COURSEWARE_EXTENSION);
			localVideoDownloadFile = new File(cacheDir, id
					+ VIDEO_COURSEWARE_DOWNLOAD_EXTENSION);
			if (localVideoCacheFile.exists()) {
				localVideoCacheFile.delete();
			}

			outRandom = new RandomAccessFile(localVideoDownloadFile, "rw");
			fileLength = outRandom.length();
			OkHttpClientManager.getInstance().downloadFile(
					TypeUtils.getJsonString(
							TypeUtils.getJsonObject(jsonObject, "resources"),
							"video"), fileLength, this);
		} catch (Exception e) {
			ErrorUtils.outErrorLog(e);
			error = ErrorUtils.SERVER_CONNECTION_ERROR;
		} finally {
			if (outRandom != null) {
				try {
					outRandom.close();
				} catch (IOException e) {
					ErrorUtils.outErrorLog(e);
				}
				outRandom = null;
			}
			fileLength = 0;

			endDownload(error == null);
		}

	}

	@Override
	public void onFailure(Request request, IOException e) {
		error = ErrorUtils.SERVER_CONNECTION_ERROR;
		ErrorUtils.outErrorLog(e);
	}

	@Override
	public void onResponse(Response response) throws IOException {
		if (iVideoCoursewareView.isResponseResult()) {
			if (response.code() == 206) {
				InputStream inputStream = null;
				ResponseBody responseBody = null;
				try {
					responseBody = response.body();
					inputStream = responseBody.byteStream();
					beginDownload();
					byte[] bbs = new byte[FILE_STREAM_BUFFER_SIZE];
					int b = -1;
					outRandom.seek(fileLength);
					fileLength = responseBody.contentLength() + fileLength;
					while ((b = inputStream.read(bbs, 0, bbs.length)) != -1) {
						outRandom.write(bbs, 0, b);
						if (!downloadStatusChange((double) outRandom.length()
								/ (double) fileLength)) {

							return;
						}
					}

				} catch (Exception e) {
					ErrorUtils.outErrorLog(e);
					error = e.getMessage();
				}

				finally {
					if (inputStream != null) {
						inputStream.close();
						inputStream = null;
					}
					if (responseBody != null) {
						responseBody.close();
					}
				}
			} else {
				error = "请求失败。" + response.code();
			}
		}
	}

	@Override
	public synchronized boolean downloadStatusChange(double completionRate) {
		if (super.downloadStatusChange(completionRate)) {
			if (iVideoCoursewareView.isResponseResult()) {

				iVideoCoursewareView.downloadStatusChange(completionRate);
				return true;
			} else {
				cancel();
				return false;
			}
		} else {
			return false;
		}
	}

	@Override
	public void downloadSuccess() {
		super.downloadSuccess();
		localVideoDownloadFile.renameTo(localVideoCacheFile);
		if (iVideoCoursewareView.isResponseResult()) {
			iVideoCoursewareView.downloadSuccess();
		}
	}

	@Override
	public void downloadError() {
		super.downloadError();
		if (iVideoCoursewareView.isResponseResult()) {
			iVideoCoursewareView.downloadVideoError(error);
		}

	}
}
